import React, { useEffect, useRef } from 'react';
import G6 from '@antv/g6';
import { compareStatus } from '../../utils/compare';
import './node';
import './edge';
import './behavior';
import './index.less';

import NodeMenu from './tool/NodeMenu';
import EdgeMenu from './tool/EdgeMenu';
import { NODE_RESULT, NODE } from './utils/constants';
import { EDGE_TYPE } from 'src/utils/constant';

export default function Graphic(props) {
  const { disabled } = props;
  const _graph = useRef();
  const _ref = useRef();
  const _edgeMenu = useRef(); // 线
  const _nodeMenu = useRef(); // 规则节点
  const _dragMap = useRef(); //拖拽的热点区域，用于框选节点

  useEffect(() => {
    init();
    return () => {
      _graph.current = null;
    };
  }, []);

  useEffect(() => {
    window.onresize = () => {
      if (!_ref.current || !_graph.current) {
        return;
      }
      const { clientWidth, clientHeight } = _ref.current;
      _graph.current.changeSize(clientWidth, clientHeight);
    };
    return () => {
      window.onresize = null;
    };
  }, []);

  useEffect(() => {
    loadCanvas();
    // 切换交互模式
    if (props.graphicMode === 'disabled') {
      _graph.current.setMode('disabled');
    } else if (props.graphicMode === 'result') {
      _graph.current.setMode('result');
    }

    function loadCanvas() {
      if (props.graphicMode === 'result') {
        // 遍历nodes,重组nodes数据
        console.log(props.value, props.flow_node_logs, props.variables);
        const edges_logs = [];
        props.flow_node_logs.forEach((node) => {
          edges_logs.push(node.edgeRuleResult || []);
        });
        const newNodes = props.value.nodes.map((item, index) => {
          const _cur = props.flow_node_logs.find((it) => {
            return it.id === item.id;
          });
          //如果从日志里面，能找到节点，说明就跑过这个节点
          if (_cur) {
            item.other = NODE_RESULT._EXEC;
            item.color = '_GREEN';
            item.longer = true;
            if (item.type === NODE._STRATEGY) {
              item.strategy_log = _cur.strategy_log;
            } else if (item.type === NODE._ACTION) {
              item.action_rule_log = _cur.action_rule_log;
            } else if (item.type === NODE._CHALLENGE) {
              item.challenge_node_log = _cur.challenge_node_log;
            }

            item.edge_rule_result = _cur.edge_rule_result;
            item.variables = props.variables;
          } else {
            if (item.type === NODE._STRATEGY) {
              item.strategy_log = { strategy_id: item.strategy_id, conditions: [] };
            }
          }
          return item;
        });
        const newEdges = props.value.edges.map((item) => {
          console.log(222, item);
          const _cur = edges_logs.find((it) => {
            return it.id === item.id;
          });
          if (_cur) {
            item.color = '_GREEN';
          }
          return item;
        });
        _graph.current.read({
          nodes: newNodes,
          edges: newEdges,
        });
      } else if (props.graphicMode === 'disabled') {
        // 如果是对比
        if (props.isCompare) {
          const { nodes, edges } = props.value;
          const newNodes = resetNodesCompareData(nodes, props.compareData && props.compareData.nodes); // 重置nodes对比的数据
          const newEdges = resetEdgesCompareData(
            nodes,
            props.compareData && props.compareData.nodes,
            edges,
            props.compareData && props.compareData.edges,
          );
          _graph.current.read({
            nodes: newNodes,
            edges: newEdges,
          });
        } else {
          _graph.current.read(props.value);
        }
      } else if (props.graphicMode === 'default') {
        _graph.current.read(props.value);
      }
    }
  }, [props.value.nodes]);

  function resetEdgesCompareData(nodes, compareNodes = [], edges, compareEdges = []) {
    //遍历edges,新增stringify字段
    edges.forEach((item) => {
      const { source, startPoint, endPoint, ...detail } = item;
      const sourceNode = nodes.find((it) => it.id === source);
      const { edge_type = EDGE_TYPE._CONDITION, edge_configs = [] } = sourceNode;
      const edge_config = edge_configs.find((it) => it.id === item.id);
      delete edge_config.edge_id; // 还原之后的数据，后端会另外生成edge_id，导致对比有问题，前端来处理，默认删除掉edge_id，不对比这个数据
      item.stringify = JSON.stringify({ edge_type, edge_config, ...detail }); // 这里对比源节点的edge_type和edge_config的线配置
    });

    //遍历对比的edges,新增stringify字段
    compareEdges.forEach((item) => {
      const { source, startPoint, endPoint, ...detail } = item;
      const sourceNode = compareNodes.find((it) => it.id === source);
      const { edge_type = EDGE_TYPE._CONDITION, edge_configs = [] } = sourceNode;
      const edge_config = edge_configs.find((it) => it.id === item.id);
      delete edge_config.edge_id; // 还原之后的数据，后端会另外生成edge_id，导致对比有问题，前端来处理，默认删除掉edge_id，不对比这个数据
      item.stringify = JSON.stringify({ edge_type, edge_config, ...detail }); // 这里对比源节点的edge_type和edge_config的线配置
    });

    // 遍历edges,重组edges数据
    return edges.map((item, index) => {
      const data = {
        isCompare: props.isCompare,
        isOld: props.isOld,
        value: item,
        compareData: compareEdges.find((it) => it.id === item.id),
      };
      const it = Object.assign({}, item);
      return compare(it, data);
    });
  }

  // 重置nodes对比的数据
  function resetNodesCompareData(nodes, compareNodes = []) {
    //遍历nodes,新增stringify字段
    nodes.forEach((item) => {
      const { edge_type, edge_configs, x, y, is_break, version, node_id, ...detail } = item;

      item.edge_type = edge_type;
      item.edge_configs = edge_configs;
      // 当是挑战者节点的时候，要深入遍历去掉version，这里因为后端的原因（版本对比的时候，后端自动生成了version），需要前端特殊处理。
      if (detail.type === NODE._CHALLENGE) {
        const _detail = {
          ...detail,
          nodes: detail.nodes.map((it) => {
            const { version, ...detail } = it;
            return detail;
          }),
        };
        item.stringify = JSON.stringify(_detail);
      } else {
        item.stringify = JSON.stringify(detail); // 这里只对比原本节点的配置，edge_type和edge_configs属于线配置
      }
    });
    //遍历nodes,新增stringify字段
    compareNodes.forEach((item) => {
      const { edge_type, edge_configs, x, y, is_break, version, node_id, ...detail } = item;
      item.edge_type = edge_type;
      item.edge_configs = edge_configs;
      // 当是挑战者节点的时候，要深入遍历去掉version，这里因为后端的原因（版本对比的时候，后端自动生成了version），需要前端特殊处理。
      if (detail.type === NODE._CHALLENGE) {
        const _detail = {
          ...detail,
          nodes: detail.nodes.map((it) => {
            const { version, ...detail } = it;
            return detail;
          }),
        };
        item.stringify = JSON.stringify(_detail);
      } else {
        item.stringify = JSON.stringify(detail); // 这里只对比原本节点的配置，edge_type和edge_configs属于线配置
      }
    });

    // 遍历nodes,重组nodes数据
    return nodes.map((item, index) => {
      const data = {
        isCompare: props.isCompare,
        isOld: props.isOld,
        value: item,
        compareData: compareNodes.find((it) => it.id === item.id),
      };
      const it = Object.assign({}, item);
      return compare(it, data);
    });
  }

  //
  function compare(it, data) {
    const result = compareStatus(data, 'stringify');
    if (result === 'update') {
      it.other = '修改';
      it.color = '_BLUE';
    }
    if (result === 'delete') {
      it.other = '删除';
      it.color = '_RED';
    }
    if (result === 'add') {
      it.other = '新增';
      it.color = '_BLUE';
    }
    it.compareData = data.compareData;
    it.isOld = data.isOld;
    it.isCompare = data.isCompare;
    return it;
  }

  // 初始化画布
  function init() {
    if (!_ref.current || _graph.current) {
      return;
    }
    const { clientWidth, clientHeight } = _ref.current;
    _graph.current = new G6.Graph({
      container: _ref.current,
      width: clientWidth,
      height: clientHeight,
      minZoom: 0.4,
      maxZoom: 1,
      fitView: true,
      fitViewPadding: [20, 40, 50, 20],
      modes: {
        // 支持的 behavior
        default: [
          {
            type: 'drag-node',
            enableDelegate: true,
          },
          {
            type: 'brush-select',
            trigger: 'drag',
            includeEdges: false,
          },
          'drag-add-node',
          'active',
          'dbclick-node-update',
        ],
        dragCanvas: ['drag-canvas'], // canvas拖拽模式
        disabled: ['dbclick-node', 'active'], // 只读模式
        result: ['drag-canvas', 'dbclick-node-result', 'edge-active-result'], // 执行结果，只读模式
      },
    });
    props.onRef && props.onRef(_graph.current);
    _graph.current._edgeMenu = _edgeMenu.current;
    _graph.current._nodeMenu = _nodeMenu.current;
    _graph.current._dragMap = _dragMap.current;
  }
  return (
    <div className='flow-graphic' id='graphic'>
      <div style={{ width: '100%', height: '600px' }} ref={(it) => (_ref.current = it)} />
      <div className='flow-menu' ref={(it) => (_edgeMenu.current = it)}>
        <EdgeMenu {...props} _graph={_graph} />
      </div>

      <div
        className='flow-menu'
        id='nodeMenu'
        ref={(it) => (_nodeMenu.current = it)}
        w={props.wp && props.wp.w}
        h={props.wp && props.wp.h}
      >
        {!disabled && <NodeMenu {...props} _graph={_graph} />}
      </div>

      <div className='draw-map' ref={(it) => (_dragMap.current = it)} />
      {/* <DragMap {...props} _graph={_graph} /> */}
    </div>
  );
}
